#include <dspSimulator/instruction/nop.h>

bool NOP::checkCondition(std::shared_ptr<DspMachine> dspMachine) {
    return true;
}

void NOP::loadInstIRIntoJit(llvm::LLVMContext *llvmContext, llvm::Module *module,
                            std::shared_ptr<llvm::IRBuilder<>> irBuilder) {

}

std::shared_ptr<Instruction> NOP::decode(std::shared_ptr<InstInfo> instInfo, u64 baseCycle) {
    std::shared_ptr<NOP> nop;
    auto dspInstInfo = std::dynamic_pointer_cast<DspInstInfo>(instInfo);
    bool isStandardInst = dspInstInfo->isStandardInstruction();
    if (isStandardInst) {
        // Standard指令
        auto data = vectorToBitSet<32>(dspInstInfo->getBits());
        if (checkBits<15>(data, 17, 0b0) && checkBits<12>(data, 1, 0b0)) {
            nop = std::make_shared<NOP>(dspInstInfo->getAddress(), baseCycle);
            nop->src1 = extractBits<4>(data, 13).to_ulong() + 1;
            nop->numOfInsertNOP = nop->src1 - 1;
            nop->p = data[0];
            nop->funcUnit = FuncUnit::UNKNOWN_FUNC;
        }
    } else {
        //Compact指令
        auto data = vectorToBitSet<16>(dspInstInfo->getBits());
        if (checkBits<13>(data, 0, 0b0110001101110)) {
            nop = std::make_shared<NOP>(dspInstInfo->getAddress(), baseCycle);
            nop->compactInstKind = "Unop";
            nop->src1 = extractBits<3>(data, 13).to_ulong() + 1;
            nop->numOfInsertNOP = nop->src1 - 1;
            nop->PROT = dspInstInfo->getPROT();
            nop->SAT = dspInstInfo->getSAT();
            nop->DSZ = dspInstInfo->getDSZ();
            nop->RS = dspInstInfo->getRS();
            nop->BR = dspInstInfo->getBR();
            nop->p = dspInstInfo->getP();
        }
    }
    return nop;
}

void NOP::executeCustom(std::shared_ptr<TargetMachine> targetMachine, ExecutePhase executePhase) {

}

std::shared_ptr<DspInstruction> NOP::clone() {
    return std::make_shared<NOP>(*this);
}

std::string NOP::toString() const {
    return m_name + " " + std::to_string(src1);
}
